package com.zlm.aspect;

import com.alibaba.fastjson.JSON;
import com.zlm.annotation.SystemLog;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.mvc.condition.RequestConditionHolder;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

/**
 * @author zlm
 * @date 2024/12/11
 * 记录日志的切面类
 */

@Component
@Aspect
@Slf4j
public class LogAspect {

    @Pointcut("@annotation(com.zlm.annotation.SystemLog)")
    public void log(){
    }

    @Around("log()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        beforeLog(joinPoint);
        Object ret;
        try {
            ret = joinPoint.proceed();
            afterLog(ret);
        } finally {
            log.info("=======log end======="+System.lineSeparator());
        }

        return ret;
    }

    private void afterLog(Object ret) {
        log.info("Response :{}",JSON.toJSONString(ret));
    }

    private void beforeLog(ProceedingJoinPoint joinPoint) {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();

        //获取被增强方法的注解对象
        SystemLog systemLog = getSytemLog(joinPoint);

        log.info("=======log start======="+System.lineSeparator());
        log.info("URL :{}",request.getRequestURI());
        log.info("BusinessName :{}",systemLog.businessName());
        log.info("Http Type:{}",request.getMethod());
        log.info("Ip :{}",request.getRemoteHost());
        log.info("Class Method :{}.{}",joinPoint.getSignature().getDeclaringTypeName(),joinPoint.getSignature().getName());
        log.info("Request Param :{}", JSON.toJSONString(joinPoint.getArgs()));


    }

    private SystemLog getSytemLog(ProceedingJoinPoint joinPoint) {
        MethodSignature methodSignature = (MethodSignature)joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        return method.getAnnotation(SystemLog.class);
    }
}
